// Agent trader in project EMarket

/* Initial beliefs and rules */

maintainer(maintainer).


/* Initial goals */
!start.

/* Plans */


+!start : maintainer(M) & .my_name(trader1) <- 
	!buy(item2, 0).
	
+!start : .my_name(trader2) <- 
	.wait(1000);
	!sell(item2, 4).
	
+!start :  .my_name(trader3) <-
	.wait(2300);
	!sell(item2, 3);
	!sell(item3, 6).




/* Goals for a trader */

/* Seller */
+!sell(Item, Price) : maintainer(Maintainer) <-
	.print( "New goal: sell ", Item, " for min price: ", Price );
	.send( Maintainer, tell, newOffer( Item ) );
	+itemRegistered( Item, Price);
	.wait( {+endOfSelling( Item, DidSell )} );
	if( DidSell == yes )
	{
		.print( "Sold ", Item );
	}
	else
	{
		.print( "Hm... not sold" );
	} 
	.



/* Buyer */
+!buy(Item, Price) : maintainer(Maintainer) <-
	.print( "New goal: buy ", Item, " for max price: ", Price );
	+buying( Item, Price );
	+currentBid( Item, Price );
	.send( Maintainer, achieve, requestOffers(Item));
	.wait( {+sellersComplete( Item )} );
	.wait( {+hasItem( Item, _ )}, 10000 );
	!doAuction( Item );
	.wait( {+endOfAuction( Item, DidBought )} );
	if( DidBought == yes )
	{
		.print( "Yeah, bought ", Item );
	}
	else
	{
		.print( "Hm... not bought", Item );
	};
	.
	
+!setCurrentBid( Item, NewPrice ) : currentBid( Item, OldPrice ) <-
	-+currentBid( Item, NewPrice );
	.
	


/* Trader received a new match from Maintainer */
/*
+newMatch( Item, Sellers ) : true <-
	.print( "Got a new Match for ", Item, ": ", Sellers );
	for( .member( Seller, Sellers ) )
	{
		+hasItem( Item, Seller );
	};
	.
*/


+sellersComplete( Item )[source(Maintainer)] : maintainer(Maintainer) & buying( Item, MinPrice )  <-		/* Maintainer notified completeness of sellers */
	.print( "Sellers complete" );
	
	.findall( Seller, hasItem( Item, Seller), ListOfSellers );
	.length( ListOfSellers, SizeSellers );
	if( SizeSellers > 0 )											/* Check if there are more than 0 sellers to auction */
	{
		.print( "Setting current bid to minPrice: ", MinPrice );
		!setCurrentBid( Item, MinPrice );
	};
	-sellersComplete( Item )[source(Maintainer)];
	.
	
+!doAuction( Item ) : currentBid( Item, Price ) & buying( Item, _ ) <-
	.print( "Starting auction for ", Item, " at Price ", Price );
	.wait( 500 );
	+replies(Item, Price, [] );
	.findall( Seller, hasItem( Item, Seller), ListOfSellers );
	
	for( .member( X, ListOfSellers ) )
	{
		.print( "Make bid to Seller: ", X, " ", Item, " ", Price );
		.send( X, tell, auctionBid(Item, Price ) );
	};
	
	+counter(0);
	+counterAgree(0);
	while( counter(X) & X < ListOfSellers )
	{
		.wait( {+reply( Item, Price, Success )[source(Seller)]}, 2000 );
		if( counterAgree(A) & Success == agree )
		{
			-+counterAgree(A+1);
		}
		-+counter(X+1)
	};
	if( counterAgree(0) )
	{
		.print( "Starting new auction" );
		!setCurrentBid( Price +1 );
		!doAuction;
	}
	else
	{
		.print( "Done!" );
	}
	.
	
/*
+hasItem( Item, Seller )[source(Maintainer)] : buying( Item ) & maintainer(Maintainer) <-
	.print( "newOfferForItem: ", Item, " from seller: ", Seller );
	.
*/
		
+itemBought( Item, Seller )[source(Maintainer)] : maintainer(Maintainer) & buying( Item, MinPrice )<-
	.print( "I am now the proud owner of ", Item, ", bought from ", Seller );
	+endOfAuction( Item, yes );
	-buying( Item, MinPrice );
	.		
	

/* Auctions for receiving on an auction bid */
/*
+replyAuctionBidAgree( Item, Price )[source(Seller)] : true <-
	.print( "Seller ", Seller, " agrees ==> end of auction" );
	.send( Seller, tell, confirmSell( Item, Price ) );	
	. 	
	
	
+replyAuctionBidRefuse( Item, Price )[source(Seller)] : replies( Item, Price, Sellers) & currentBid( Item, CurrentBid ) <-
	.print( "Seller ", Seller, " refuses => continue" );
	-replies( Item, Price, _ )[ source(self) ];
	
	
	.findall( Seller, hasItem( Item, Seller), ListOfSellers );
	.length( Sellers, SizeReplies );
	.length( ListOfSellers, SizeSellers );
	 
	if( (SizeReplies+1) == SizeSellers )
	{
		.print( "all refuse replies received" );
		-replies( Item, Price, _ )[ source(self) ];
		!setCurrentBid( Item, (CurrentBid+1) );
		!doAuction( Item );
	};
	+replies( Item, Price, [Seller|Sellers] );
	.
*/
	
/* TODO: When all Sellers refuse and next price is to high for new round, +endOfAuction( Item, 0 ) */	
	
	
/* TODO: when replies(I,S) is "full", choose next action */
	
	
	
/* Actions for replying to an auction bid */	
+auctionBid( Item, Price )[source( Buyer )] : itemRegistered( Item, PriceToSell ) <-
	if( Price >= PriceToSell & not sendAgree( Item, _, _ ) )		/* Note: use "not" to check if something isn't in the database, ~ for explicit false */
	{
		.print( "Agree to offer: ", Item, " ", Price );
		+sendAgree( Item, Price, Buyer );
		/*.send( Buyer, tell, replyAuctionBidAgree( Item, Price ) ); */
		.send( Buyer, tell, reply( Item, Price, agree ) );
	}
	else
	{
		.print( "Refuse to offer: ", Item, " ", Price );
		/* .send( Buyer, tell, replyAuctionBidRefuse( Item, Price ) ); */
		.send( Buyer, tell, reply( Item, Price, refuse ) );
	}
	-auctionBid( Item, Price )[source( Buyer )];
	.
	
	
	
	
+confirmSell( Item, Price )[source( Buyer )] : sendAgree( Item, Price, Buyer ) & maintainer(Maintainer) <-
	.send( Maintainer, achieve, itemSold( Item, Buyer ) );
	-itemRegistered( Item, Price );
	-sendAgree( Item, Price, Buyer )[source(Buyer)];
	+
	.print( "Item ", Item, " is sold to ", Buyer, " for price ", Price );
	.
	
+refuseSell( Item, Price )[source( Buyer )] : sendAgree( Item, Price, Buyer ) <-
	-sendAgree( Item, Price, Buyer )[source(Buyer)];
	.print( "Buyer ", Buyer, " don't wants to buy ", Item, " for price ", Price, " ;(" );
	.	
	
/* TODO: When buying an Item, remove buying( Item ) from believe base */
	
